<?php
require_once 'vendor/autoload.php';
use \Firebase\JWT\JWT;
use Firebase\JWT\Key;
/**
 * 平台支持手机验证码登录（阿里云短信）
 * 
 */
class LoginController extends Controller {
    private $width;//宽度
    private $height; //高度
    private $codeNum;//验证码字符数量
    private $redisObj;//redis对象
    private $captcha;//验证码字符串
    const charWidth = 10;//单个字符宽度,根据输出字符大小而变
    private $image;//验证码图像资源
    private $ext;// 扩展配置
    function __construct(){
        parent::__construct();
        $this->redisObj = new ZDRedis();
        $this->width=230;
        $this->height=46;
        $this->codeNum=4;
        $this->ext = $GLOBALS['ext'];
    }
    function init(){
		header("Content-type: text/html; charset=utf-8");
		require(APP_DIR.'/protected/include/functions.php');
		  
	}
    /**
     * 从Token中解析用户ID
     */
    function getLoginUserId(){
        try {
            $token = getToken();
            if (empty($token)) {
                throw new Exception('Token为空');
            }
            $secretKey = $GLOBALS['JWT_SECRET_KEY'];
            $key = new Key($secretKey , 'HS256');
            $decoded = JWT::decode($token, $key);
            $userId = $decoded->userId;
            return $userId;
        } catch (Exception $e) {
            return false;
        }
    }
    /**
     * 获取图形验证码
     */
    function  actionAuthcode(){
        $u = (string)arg("u","");
        if(empty($u) || !isset($u)){
            error("请输入手机号");
        }
        $this->createImage();
        $this->setDisturb();
        $this->setCaptcha();
        $this->exportImage($u);
    }
    /**
     * 获取手机验证码
     */
    function actiongetMobileCode(){
        $phone = (string)arg("phone","");
        if(empty($phone) || !isset($phone)){
            error("请输入手机号");
        }
        $imgCaptcha = (string)arg("imgCaptcha","");
        if(empty($imgCaptcha) || !isset($imgCaptcha)){
            error("请输入图形验证码");
        }
        $redisCaptcha = $this->redisObj->get("authcode:{$phone}");
        if(empty($redisCaptcha) || !isset($redisCaptcha)){
            error("请先获取图形验证码");
        }
        if($imgCaptcha != $redisCaptcha){
            error("图形验证码错误");
        }
        $mobileCode = rand(1000,9999);
        $this->redisObj->set("mobilecode:{$phone}",$mobileCode,60*5);// 生成手机验证码
        try {
            // 替换为你的AccessKeyId和AccessKeySecret
            $accessKeyId = $this->ext['Aliyun']['accessKeyId'];
            $accessKeySecret = $this->ext['Aliyun']['accessKeySecret'];
            $signName = $this->ext['Aliyun']['signName'];
            $templateCode = $this->ext['Aliyun']['templateCode'];
            
            // 初始化短信发送器
            $smsSender = new AliSms($accessKeyId, $accessKeySecret);
            
            // 发送短信
            $templateParam = [
                'code' => $mobileCode 
            ];
            
            $result = $smsSender->sendSmsCode($phone, $signName, $templateCode, $templateParam);
            
            // 处理返回结果
            if ($result) {
                success(array(),"发送成功");
            } else {
                error("短信发送失败:");
            }
        } catch (Exception $e) {
            error("发送失败: " . $e->getMessage());
        }
    }
    /**
     * 登录首页
     */
    function actionIndex(){}

    /**
     * 构造图像，设置底色
     */
    private function createImage() {
        //创建图像
        $this->image = imagecreatetruecolor($this->width, $this->height);
        //创建背景色
        $bg = imagecolorallocate($this->image, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
        //填充背景色
        imagefilledrectangle($this->image, 0, 0, $this->width - 1, $this->height - 1, $bg);
    }
    /**
     * 设置干扰元素
     */
    private function setDisturb() {

        //设置干扰点
        for($i = 0; $i < 150; $i++) {
            $color = imagecolorallocate($this->image, mt_rand(150, 200),  mt_rand(150, 200),  mt_rand(150, 200));
            imagesetpixel($this->image, mt_rand(5, $this->width - 10), mt_rand(5, $this->height - 3), $color);
        }

        //设置干扰线
        for($i = 0; $i < 10; $i++) {
            $color = imagecolorallocate($this->image, mt_rand(150, 220), mt_rand(150, 220), mt_rand(150, 220));
            imagearc($this->image, mt_rand(-10, $this->width), mt_rand(-10, $this->height), mt_rand(30, 300), mt_rand(20, 200), 55, 44, $color);
        }

        //创建边框色
        $border = imagecolorallocate($this->image, mt_rand(0, 50), mt_rand(0, 50), mt_rand(0, 50));
        //画边框
        imagerectangle($this->image, 0, 0, $this->width - 1, $this->height - 1, $border);
    }
    /**
     * 产生并绘制验证码
     */
    private function setCaptcha() {
        $str = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
        
        // 确保高度足够大，避免y坐标计算问题
        if ($this->height < 22) {
            $this->height = 22;
        }
        
        //生成验证码字符
        for($i = 0; $i < $this->codeNum; $i++) {
            $this->captcha .= $str[mt_rand(0, strlen($str) - 1)];
        }
        
        //绘制验证码
        for($i = 0; $i < strlen($this->captcha); $i++) {
            $color = imagecolorallocate($this->image, mt_rand(0, 200), mt_rand(0, 200), mt_rand(0, 200));
            $x = floor(($this->width - 10)/$this->codeNum);
            $x = $x*$i + floor(($x-self::charWidth)/2) + 5;
            $y = mt_rand(2, $this->height - 20);
            imagechar($this->image, 5, $x, $y, $this->captcha[$i], $color);
        }
    }
    /*
     * 输出图像,验证码保存到session中
     */
    private function exportImage($u) {
        if(imagetypes() & IMG_GIF){
            header('Content-type:image/gif');
            imagegif($this->image);
        } else if(imagetypes() & IMG_PNG){
            header('Content-type:image/png');
             imagepng($this->iamge);
        } else if(imagetypes() & IMG_JPEG) {
            header('Content-type:image/jpeg');
             imagepng($this->iamge);
        } else {
            imagedestroy($this->image);
            die("Don't support image type!");
        }
        //将验证码信息保存到redis中，md5加密,验证码1分钟过期
        $this->redisObj->set("authcode:".$u,strtolower($this->captcha),60,"ma");
        imagedestroy($this->image);
    }

    /**
     * 生成token
     */
    private function generateToken($userId, $duration = 86400) {
        // 设置 JWT 的 Payload 信息
        $payload = array(
            "iss" => "kpCheck", // 签发者
            "aud" => "kpCheck", // 接收方
            "iat" => time(), // 签发时间
            "exp" => time() + $duration, // 过期时间
            "userId" => $userId // 你可以根据需要添加更多信息
        );
        $secretKey = $GLOBALS['JWT_SECRET_KEY'];
        // 生成 JWT
        $jwt = JWT::encode($payload, $secretKey, 'HS256',$secretKey);
        
        return $jwt;
    }
    /**
     * 登录操作
     */
    function actionLogin(){
        $phone = (string)arg("phone","");
        if(empty($phone) || !isset($phone)){
            error("请输入手机号");
        }
        $imgCaptcha = (string)arg("imgCaptcha","");
        if(empty($imgCaptcha) || !isset($imgCaptcha)){
            error("请输入图形验证码");
        }
        $smsCaptcha = (string)arg("smsCaptcha","");
        if(empty($smsCaptcha) || !isset($smsCaptcha)){
            error("请输入短信验证码");
        }
        $captcha = $this->redisObj->get("authcode:".$phone);
        if(strtolower($imgCaptcha) != strtolower($captcha)){
            error("图形验证码错误");
        }
        $smsCaptcha = $this->redisObj->get("mobilecode:".$phone);
        if(strtolower($smsCaptcha) != strtolower($smsCaptcha)){
            error("短信验证码错误");
        }
        // 查询用户是否存在，用户不存在则自动注册，注册后需要超级管理员赋予权限
        $user = new Auditor();
        $userData = $user->find(array("mobile"=>$phone));
        if($userData == false){   
            // 随机生成用户的用户名字符串，要结合审核系统
            $real_name = RandomUsernameGenerator::generate('mix', 10);
            $generator = new AvatarGenerator();
            $avatar = $generator->generate(200, $real_name);
            $filename = 'avatar_'.generateUUID().'.svg';
            $generator->saveToFile($avatar, "i/avatar/".$filename);
            // 用户注册
            $newRow = array(
                "username"=>$phone,
                "real_name"=>$real_name,
                "avatar"=>$filename,
                "status"=>1,
                "last_login_time"=>date("Y-m-d H:i:s"),
                "mobile"=>$phone,
            );
            $addid = $user->create($newRow);
            if($addid){
                $token = $this->generateToken($addid);
                success(["token"=>$token]);
            }else{
                error("注册失败");
            }
        }else{
            // 用户存在，生成token返回登录token
            $token = $this->generateToken($userData["id"]);
            success(["token"=>$token]);
        }
    }

    /**
     * 检查用户是否已经登录
     */
    function actionChkLogin(){
        $uid = (int)arg("uid",0);
		$appid = (int)arg("appid",0);
    }

}